package com.thinkgem.jeesite.modules.weixin.pageauthorization;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by yangrui on 2018/4/1.
 */
public class CacheTokenAndTicket {
    private static final Logger logger = LoggerFactory.getLogger(CacheTokenAndTicket.class);
    private static final String Access_Token_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
    private static final String JSAPI_Ticket_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
    public static Map<String, AccessToken> tokenMap = new HashMap<>(1);
    public static Map<String, JSAPITicket> ticketMap = new HashMap<>(1);

    private static String appId = "";
    private static String appSecret = "";

    static {
        AccountConfig accountConfig = new AccountConfig();
        accountConfig.getConfig();
        appId = accountConfig.getAppId();
        appSecret = accountConfig.getAppSecret();
    }

    /**
     * 获取access_token
     * @return
     * @throws Throwable
     */
    public static synchronized AccessToken getAccessToken() {
        AccessToken token = tokenMap.get(appId);
        // 内存中的token不存在或者存在却已经过期，则调用接口生成一个新的
        if (token == null || token.isInVaild()) {
                String formatAccessTokenURL = String.format(CacheTokenAndTicket.Access_Token_URL, appId, appSecret);
                String resp = ReqToWeixin.httpGet(formatAccessTokenURL);
                Gson gson = new Gson();
                token = gson.fromJson(resp, new TypeToken<AccessToken>(){}.getType());
                // 正确返回结果：{"access_token":"ACCESS_TOKEN","expires_in":7200}
                // 错误返回结果（该示例为AppID无效错误）：{"errcode":40013,"errmsg":"invalid appid"}
                if (token.getErrcode() != null) {
                    logger.error(resp);
                } else {
                    token.setCreateTime(System.currentTimeMillis());
                    tokenMap.put(appId, token);
                }
        }
        return token;
    }

    /**
     * 获取js_ticket
     * @return
     * @throws Throwable
     */
    public static synchronized JSAPITicket getJSAPITicket( ) throws Throwable {
        JSAPITicket ticket = ticketMap.get(appId);
        AccessToken token = getAccessToken();
        if(token == null || token.isInVaild()){
            getAccessToken();
        }
        if(token != null && !token.isInVaild()){
            // 内存中的token不存在或者存在却已经过期，则调用接口生成一个新的
            if (ticket == null || ticket.isInVaild()) {
                String formatJSAPITicketURL = String.format(CacheTokenAndTicket.JSAPI_Ticket_URL, token.getAccess_token());
                String resp = ReqToWeixin.httpGet(formatJSAPITicketURL);
                Gson gson = new Gson();
                ticket = gson.fromJson(resp, new TypeToken<JSAPITicket>(){}.getType());
                ticket.setAppId(appId);
                if (ticket.getErrcode() != null && ticket.getErrcode() == 0) {
                    ticket.setCreateTime(System.currentTimeMillis());
                    ticketMap.put(appId, ticket);
                } else {
                    logger.error(resp);
                }
            }
            logger.debug("ticket获取成功！");
            return ticket;
        }
        logger.debug("access_token获取失败！");
        return null;
    }

    public static void main(String[] args) throws Throwable {

    }
}
